﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class BrokenPipeTag
	{
		public BrokenPipeTag(Autodesk.Revit.DB.Document doc)
		{
			this.doc = doc;
			this.InitializeData();
		}

		public void Execute()
		{
			for (;;)
			{
				try
				{
					this.transaction = new Transaction(this.doc, "断管符号标注");
					this.transaction.Start();
					this.GetTagPipes();
					this.GetConnector();
					if (!this.CreateDetailCurveTag())
					{
						YJKMessageBox.Show("您选择的管段不需要进行断管符号标注!");
						continue;
					}
					this.transaction.Commit();
					this.transaction = new Transaction(this.doc, "创建管道符号标注详图组");
					this.transaction.Start();
					this.SetBrokenPipeTagLineStyle();
					this.CreatDetailCurveGroup();
					this.transaction.Commit();
					this.doc.Regenerate();
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException ex)
				{
					ex.ToString();
				}
				catch (Exception ex2)
				{
					ex2.ToString();
					continue;
				}
				finally
				{
					if (this.transaction != null && ((int)this.transaction.GetStatus() == 1 || (int)this.transaction.GetStatus() == 5))
					{
						this.transaction.RollBack();
					}
				}
				break;
			}
		}

		private void InitializeData()
		{
			this.uiDoc = new UIDocument(this.doc);
			this.sel = this.uiDoc.Selection;
			this.scale = (double)this.doc.ActiveView.Scale / 100.0;
		}

		private void GetTagPipes()
		{
			this.pipes.Clear();
			IList<Element> list;
			do
			{
				list = this.sel.PickElementsByRectangle(new PipeFilter(), "请选择需要标注的管道...");
			}
			while (list.Count == 0);
			foreach (Element element in list)
			{
				this.pipes.Add(element as Pipe);
			}
		}

		private void GetConnector()
		{
			this.dicConnectors.Clear();
			foreach (Pipe pipe in this.pipes)
			{
				XYZ value = ((pipe.Location as LocationCurve).Curve.GetEndPoint(0) + (pipe.Location as LocationCurve).Curve.GetEndPoint(1)) / 2.0;
				ConnectorSetIterator connectorSetIterator = pipe.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector key = obj as Connector;
					this.dicConnectors.Add(key, value);
				}
			}
		}

		private bool CreateDetailCurveTag()
		{
			bool result = false;
			foreach (KeyValuePair<Connector, XYZ> connector in this.dicConnectors)
			{
				if (!connector.Key.IsConnected)
				{
					this.detailCurves.Add(this.DrawDetailCurve(connector));
					result = true;
				}
			}
			return result;
		}

		private ElementSet DrawDetailCurve(KeyValuePair<Connector, XYZ> connector)
		{
			ElementSet elementSet = new ElementSet();
			Connector key = connector.Key;
			XYZ xyz = new XYZ(key.Origin.X, key.Origin.Y, 0.0);
			XYZ xyz2 = new XYZ(connector.Value.X, connector.Value.Y, 0.0);
			XYZ xyz3 = (xyz - xyz2).Normalize();
			XYZ xyz4 = xyz;
			XYZ xyz5 = Transform.CreateRotation(new XYZ(0.0, 0.0, -1.0), Math.PI*.5).OfVector(xyz3).Normalize();
			DetailCurve detailCurve = this.doc.CreatYJKDetailCurve(Arc.Create(xyz4, xyz4 + xyz5 * this.scale * 100.0 / 304.8, xyz4 + xyz3 * (58.0 - Math.Sqrt(864.0)) * this.scale / 304.8 + xyz5 * 50.0 * this.scale / 304.8));
			DetailCurve detailCurve2 = this.doc.CreatYJKDetailCurve(Arc.Create(xyz4, xyz4 - xyz5 * this.scale * 100.0 / 304.8, xyz4 - xyz3 * (58.0 - Math.Sqrt(864.0)) * this.scale / 304.8 - xyz5 * 50.0 * this.scale / 304.8));
			elementSet.Insert(detailCurve);
			elementSet.Insert(detailCurve2);
			return elementSet;
		}

		private void CreatDetailCurveGroup()
		{
			foreach (ElementSet eleSet in this.detailCurves)
			{
				AssociationMarkInfo.WriteMarkInfoToElement(RevitVersionFuncs.NewGroup(this.doc, eleSet), MarkType.PipeLevel);
			}
		}

		private void SetBrokenPipeTagLineStyle()
		{
			ElementId elementId = null;
			foreach (ElementSet elementSet in this.detailCurves)
			{
				foreach (object obj in elementSet)
				{
					DetailCurve detailCurve = (DetailCurve)obj;
					if (elementId == null)
					{
						elementId = SetLineType.ReturnLineStyleId(this.doc, detailCurve, "BrokenPipeTagLineType");
					}
					using (SubTransaction subTransaction = new SubTransaction(this.doc))
					{
						subTransaction.Start();
						detailCurve.get_Parameter(BuiltInParameter.BUILDING_CURVE_GSTYLE).Set(elementId);
						subTransaction.Commit();
					}
					this.doc.Regenerate();
				}
			}
		}

		private Document doc;

		private UIDocument uiDoc;

		private Selection sel;

		private List<Pipe> pipes = new List<Pipe>();

		private Dictionary<Connector, XYZ> dicConnectors = new Dictionary<Connector, XYZ>();

		private Transaction transaction;

		private List<ElementSet> detailCurves = new List<ElementSet>();

		private double scale = 1.0;
	}
}
